<?php
class DigCms_Service_Item {
    
    /**
     * the modules can register content types with the CMS
     * which integrates them with the page editor
     * 
     * a content type is made up of an alias, the module and the controller
     *
     * @var unknown_type
     */
    protected static $_itemKey = 'DigCms_Item_type';

    /**
     * maps a path to the item
     *
     * this is mapped based on the item name
     *
     * @param string $path
     * @param bool $global
     * @return DigCms_Model_Item
     */
    public static function getItemByPath($path, $global = true) {
        if (empty($path) || $path == '/') {
            return false;
        }
        $pathParts = explode('/', $path);
        $itemModel = new DigCms_Model_Item();
        $model = $itemModel->model();
        if (count($pathParts) > 0) {
            if($global == true) {
                $parentId = Dig_Service_Module::settings('digCms', 'contentRootId');
            } else {
                $parentId = self::getDefaultItem()->id;
            }
            foreach ($pathParts as $part) {
                if (! empty($part)) {
                    $select = $model->select()
                            ->where('parent_id = ?', $parentId)
                            ->where('name = ?', $part);
                    $row = $model->fetchRow($select);
                    if(! $row) {
                        return false;
                    }
                    $parentId = $row->id;
                }
            }
            if($row) {
                return DigCms_Model_Item::factory($row);
            }
        }
        return false;
    }

    public static function properties($item) {
        $itemType = self::getItemTypeDetails($item->namespace);
        $author = DigUser_Service_User::getUserById($item->created_by);
        $createdBy = $author->first_name . ' ' . $author->last_name;
        $editor = DigUser_Service_User::getUserById($item->updated_by);
        if($editor) {
            $updatedBy = $editor->first_name . ' ' . $editor->last_name;
        } else {
            $updatedBy = null;
        }
        $path = DigNavigation_Service_Menu::getUrlForItem($item);
        $link = htmlentities('<a href="/' . $path . '">' . DigNavigation_Service_Menu::getLabel($item) . '</a>');
        $props = array(
            'id'            => $item->id,
            'name'          => $item->name,
            'date_created'  => date('m/d/Y h:i', $item->date_created),
            'author'        => $createdBy,
            'last_updated'  => date('m/d/Y h:i', $item->date_updated),
            'updated_by'    => $updatedBy,
            'path'          => '/' . $path,
            'link'          => $link,
            'module'        => !empty($itemType['module']) ? $itemType['module'] : 'Default',
            'controller'    => !empty($itemType['controller']) ? $itemType['controller'] : 'Default'
        );
        $fields = $item->properties();
        sort($fields);
        return array_merge($props, $fields);
    }

    
    /**
     * this returns the default item, which will be used as the home page
     */
    public static function getDefaultItem()
    {
        $itemId = Dig_Service_Module::settings('digCms', 'siteRootId');
        return DigCms_Model_Item::factory($itemId);
    }

    public static function isDefaultItem(DigCms_Model_Item $item) {
        return $item->id == self::getDefaultItem()->id;
    }
    
    public static function setDefaultType($type)
    {
        Dig_Service_Core::setParam(self::$_itemKey . '_default', $type);
    }

    /**
     * returns the default item type details
     * 
     * @return array
     */
    public static function getDefaultType()
    {
        $type = Dig_Service_Core::getParam(self::$_itemKey . '_default');
        return self::getItemTypeDetails($type);
    }
    
    /**
     * this method registers all of the items which are configured in the module config files
     * 
     * @example you configure an item as follows:
     * item.test.name = "Test Item"
     * item.test.controller = myController
     * item.test.default = false
     *
     */
    public static function registerItems()
    {
        $modules = Dig_Service_Module::listAll();
        foreach ($modules as $module => $moduleConfig) {
            if(isset($moduleConfig['item'])) {
                foreach ($moduleConfig['item'] as $config) {
                    $controllerName = $config['controller'];
                    self::registerItem(
                        $config['name'], 
                        $module, 
                        $controllerName,
                        isset($config['icon']) ? $config['icon'] : null,
                        (isset($config['default']) && $config['default'] == 1));
                }
            }
        }
    }
    
    public static function registerItem($name, $module,$controller, $icon = null, $makeDefault = false)
    {
        $namespace = ucfirst($module) . '_Model_' . $controller;
        if($makeDefault) {
            self::setDefaultType($namespace);
        }
        
        $types = self::getItemTypes();
        if(!$types) {
            $types = array();
        }
        $filter = new Zend_Filter_Word_CamelCaseToDash();
        $controller = $filter->filter($controller);
        $controller = strtolower($controller);
        $types[$namespace] = array(
            'name'		    => $name,
            'module'	    => $module,
            'controller'    => $controller,
            'icon'          => $icon,
            'namespace'     => $namespace
        );
        Dig_Service_Core::setParam(self::$_itemKey, $types);
    }
    
    public static function getItemTypes()
    {
        if(Dig_Service_Core::hasParam(self::$_itemKey)) {
            return Dig_Service_Core::getParam(self::$_itemKey);
        }
    }

    /**
     * returns the item type details for the specified item
     * if they are not set then it uses the default type
     * 
     * @param DigCms_Model_Item $item
     * @return array
     */
    public static function getItemType($item)
    {
        $details = self::getItemTypeDetails($item->namespace);
        if(empty($details)) {
            $details = self::getDefaultType();
        }
        return $details;
    }
    
    public static function getItemTypeDetails($type)
    {
        $types = self::getItemTypes();
        if(isset($types[$type])) {
            return $types[$type];
        }
    }
    
    public static function getPublishLevels()
    {
        return array(
            0    => 'Not published',
            1    => 'Published to Staging Only',
            2    => 'Published',
            3    => 'Archived'
        );
    }
    
    /**
     * this function just converts the namespace to a human friendly version
     * the namespace is the classname of the item model
     * 
     * @example 'DigContent_Model_Page' will become 'Content Page'
     *
     * @param string $namespace
     */
    public static function getLabelForNamespace($namespace)
    {
        $namespace = str_replace('Dig', '', $namespace);
        $namespace = str_replace('_Model_', ' ', $namespace);
        return trim($namespace);
    }

    /**
     * this function inspects a controllers name and attempts to map it
     * to the corresponding model and form.
     *
     * @param string $controllerName
     */
    public static function mapControllerToResources($controllerName) {
        //Zend_Debug::dump($controllerName);
        $parts = explode('_', $controllerName);
        $resource['module'] = $parts[0];
        $moduleFolder = $resource['module'];
        $moduleFolder[0] = strtolower($moduleFolder[0]);
        $modulePath = APPLICATION_PATH . '/modules/' . $moduleFolder;
        $resource['controller'] = $controllerName;
        $item  = str_replace('Controller', '', $parts[1]);
        $pathToModel = $modulePath . '/models/' . $item . '.php';
        $pathToForm = $modulePath . '/models/' . $item . '.php';
        $resource['model'] = (file_exists($pathToModel)) ? $resource['module'] . '_Model_' . $item : false;
        $resource['form'] = (file_exists($pathToForm)) ? $resource['module'] . '_Form_' . $item : false;
        return $resource;
    }

    /**
     *
     * @param mixed $item path, id or item
     * @param string $format xhtml or object, xhtml is the default and renders the content, object is a simpleXml object
     * @return mixed
     */
    public static function asXhtml($item, $format = 'xhtml') {
        $view = Zend_Layout::getMvcInstance()->getView();
        $item = DigCms_Model_Item::factory($item);
        $content = $view->digCmsRenderItem($item);
        if($format == 'xhtml') {
            return $content;
        }
        try{
            $content = str_replace('&', '&amp;', $content);
          $xml = @simplexml_load_string('<item>' . $content . '</item>');
        } catch (DigCms_Exception $e) {
            echo 'Unable to parse item as XML';
        }
        return $xml;
    }
}